<?php

$loader->requireOnce('includes/RadQueue/RadQueueProcessor.class.php');
$loader->requireOnce('includes/RadUtils.class.php');
$loader->requireOnce('includes/RadProcessor/RadProcessorFactory.class.php');
$loader->requireOnce('includes/ResultParser/ResultParser.class.php');
$loader->requireOnce('includes/ResultParser/DICOMParser.class.php');
$loader->requireOnce('includes/ResultParser/ImageParser.class.php');
$loader->requireOnce('includes/RadConnector/RadConnectorFactory.class.php');

class C_RadResult extends Controller {
    private $logger ;

    function __construct($template_mod = "general") {
        parent::__construct($template_mod);
        if (Celini::getCurrentController() == 'RadResult') {
            $menu =& Menu::getInstance();
            $menu->currentSection = 'patient';
        }
        $this->logger = LoggerManager::getLogger('module.dept_rad.controllers.C_RadResult');
        $this->template_mod = $template_mod;
        $this->view->path="rad_result";
    }

    function actionStartTicketAjax() {
        /*
         * 1. Check if the ticket is in RadInProgress queue or not.
              If not, move the ticket to RadInProgress queue.
         * 2. Redirect user to radiology result input page
        */
    	$result = array(
                    'error'     =>  array('code'=>CoreErrorCode::NORMAL, 'mess'=>''),
                    'result'    =>  ''
        );
        $radTicketId  =   $_GET['radTicketId'];
        $this->logger->info("Start action StartTicketAjax {radTicketId=$radTicketId}");
        try {
            if (!RadQueueProcessor::checkQueueItemExist($radTicketId, ARadQueue::QUEUE_TYPE_INPROGRESS)) {
                RadQueueProcessor::moveQueueItem($radTicketId, ARadQueue::QUEUE_TYPE_INPROGRESS);
            }
            // HIS: doAfterStartAssignment
            $objRadTicket   =   Celini::newORDO('RadTicket', $radTicketId);
            $objConnector   =   RadConnectorFactory::createConnector($objRadTicket->getEnumPatientType());
            $objConnector->doAfterStartAssignment($radTicketId, RadUtils::convertToTicketItemType($objRadTicket->getEnumRadType()));
            $result['result']   =   Celini::link('LoadResultInputPage', 'RadResult'). "radTicketId=$radTicketId";

        }
        catch(RadException $ex) {
            $result['error']['code']    =   $ex->getErrorCode();
            $result['error']['mess']    =   CoreErrorCode::getErrorMess($ex->getErrorCode());
            $this->logger->error('Action StartTicket fail. Error message: '. $ex->getMessage());
        }
        catch(Exception $ex){
        	$result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
            $this->logger->error('Action StartTicket fail. Error message: '. $ex->getMessage());
        }
        $this->logger->info("Finish action StartTicketAjax {radTicketId=$radTicketId}");

        return json_encode($result);
    }

    public function actionLoadResultInputPage($radTicketId = 0) {
        $radTicketId   =   EnforceType::int($_GET['radTicketId']);
    	$objRadTicket  =   Celini::newORDO('RadTicket', $radTicketId);
        // Patient info
    	$objPatient    =   Celini::newORDO('Patient', $objRadTicket->getPatientId());
    	$objPerson     =   Celini::newORDO('Person', $objRadTicket->getPatientId());
        $this->assign('patientName', $objPerson->getName());
        $this->assign('patientCode', $objPatient->getPatientCode());
        $this->assign('patientDob', $objPerson->getDateofBirth());
        $this->assign('patientAge', $objPerson->getAge());

        // All opening ticket of patient
        $rawList        =   ORDataObject::factory('RadTicket')->getAssignmentsByPatient($objRadTicket->getPatientId(),
            Utils::getEnumKey(EnumerationConstant::RAD_TICKET_STATUS, EnumerationConstant::RAD_TICKET_STATUS_INPROGRESS));
        $ticketList     =   RadUtils::getAssignmentListKeyValue($rawList, true);
        $this->assign('radTicketList', $ticketList);
        $this->assign('radTicketId', $radTicketId);

    	return $this->view->render('result_input.html');
    }

    public function actionLoadResultInputAjax($radTicketId = 0) {
        $result = array(
                    'error'     =>  array('code' => CoreErrorCode::NORMAL,
                                          'mess' => ''),
                    'result'    =>  ''
        );
    	$radTicketId    =   EnforceType::int($_GET['radTicketId']);
        $this->logger->info("Start action LoadResultInputAjax {radTicketId=$radTicketId}");
        try {
            $objRadTicket   =   Celini::newORDO('RadTicket', $radTicketId);
            $objProcessor   =   RadProcessorFactory::createProcessor($objRadTicket->getEnumRadType());
            $result['result']   =   $objProcessor->loadResultInput($radTicketId);
        }
        catch(RadException $ex) {
            $result['error']['code']    =   $ex->getErrorCode();
            $result['error']['mess']    =   CoreErrorCode::getErrorMess($ex->getErrorCode());
            $this->logger->error('Action StartTicket fail. Error message: '. $ex->getMessage());
        }
        catch(Exception $ex){
            $result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
            $this->logger->error('Action StartTicket fail. Error message: '. $ex->getMessage());
        }
        $this->logger->info("Finish action LoadResultInputAjax {radTicketId=$radTicketId}");

        return json_encode($result);
    }

    public function actionUploadImageAjax() {
    	$result = array(
                    'error'     =>  array('code' => CoreErrorCode::NORMAL,
                                          'mess' => ''),
                    'result'    =>  ''
        );

        $radTicketItemId    =   $_POST['radTicketItemId'];
        $fileType           =   $_FILES['userfile']['type'];
        $ext                =   strtolower(end(explode(".", $_FILES['userfile']['name'])));
        $this->logger->info("Start action UploadImageAjax {radTicketItemId='$radTicketItemId', fileExtension='" . $ext . "'}");
        try {
        	if (!isset($_FILES['userfile'])) {
                $msg    =   "Probably the uploaded file is too larger";
                throw new CoreException($msg, CoreErrorCode::UPLOAD_ERR_FILE_TOO_LARGE);
        	}
            $allowedExtensions  =   array('gif', 'jpe', 'jpeg', 'jpg', 'png', 'dcm');
	        $msg = '';
	        if (!empty($_FILES['userfile']['error'])) {
	            switch($_FILES['userfile']['error']) {
	                case UPLOAD_ERR_INI_SIZE:
	                    $msg = 'The uploaded file exceeds upload_max_filesize directive in php.ini';
	                case UPLOAD_ERR_FORM_SIZE:
	                    $msg = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
	                case UPLOAD_ERR_PARTIAL:
	                    $msg = 'The uploaded file was only partially uploaded';
	                case UPLOAD_ERR_NO_FILE:
	                    $msg = 'No file was uploaded';
	                case UPLOAD_ERR_NO_TMP_DIR:
	                    $msg = 'Missing a temporary folder';
	                    break;
	                case UPLOAD_ERR_CANT_WRITE:
	                    $msg = 'Failed to write file to disk';
	                case UPLOAD_ERR_EXTENSION:
	                    $msg = 'File upload stopped by extension';
	                case '999':
	                default:
	                    $msg = 'Unknown upload error';
	            }
	            throw CoreException($msg, CoreErrorCode::UPLOAD_ERR_COMMON);
	        }
	        elseif (!in_array($ext, $allowedExtensions)) {
	            $msg = "File type $ext is not allowed";
	            throw new CoreException($msg, CoreErrorCode::UPLOAD_ERR_EXTENSION_NOT_ALLOWES);
	        }
	        else {
	        	// Initialize a result parser object, set approciate parser engine based on file extension
	            $objResultParser   =   new ResultParser();
	            switch ($ext){
                    case "dcm":
                        $perserEngine   =   new DICOMParse();
                        break;
                    default:
                    	$perserEngine   =   new ImageParser();
                    	break;
	            }
	            $objResultParser->setParserEngine($perserEngine);
	            $objRadImage  =   ORDataObject::factory('RadResultImage');
                // Create directoies for images
                $location     =   $objRadImage->createImageDirectories($radTicketItemId);
	            // Parsing image
	            $this->logger->info("Start parsing image {fileExtension='$ext'}");
                $images =   $objResultParser->parse($_FILES['userfile'], $location['full'], $location['thumbnail'], $ext, 170, 170);
                $this->logger->info("Finish parsing image {fileExtension='$ext''}");

                // Set image data to database
                $objRadImage->setData($radTicketItemId, $images['full'], $images['thumbnail']);
                $objRadImage->persist();

                // Build return data
                $result['result']   =   array(
                    'radImageId'    =>  $objRadImage->get_id(),
                    'fullUrl'       =>  Utils::getAppUrl() . $objRadImage->getFullUrl(),
                    'thumbnailUrl'  =>  Utils::getAppUrl() . $objRadImage->getThumbnailUrl(),
                );
	        }

        }
        catch (CoreException $ex) {
            $result['error']['code'] = $ex->getErrorCode();
            $result['error']['mess'] = CoreErrorCode::getErrorMess($ex->getErrorCode());
            $this->logger->error('Action UploadImageAjax fail. Error message: '. $ex->getMessage());
        }
        catch (Exception $ex){
            $result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
            $this->logger->error('Action UploadImageAjax fail. Error message: '. $ex->getMessage());
        }
        $this->logger->info("Finish action UploadImageAjax {radTicketItemId='$radTicketItemId', fileExtension='" . $ext . "'}");

        return json_encode($result);
    }

    private function buildImageBlock($radImageId, $fullUrl, $thumbnailUrl, $showDelButton) {
        $fullUrl        =  Utils::getAppUrl() . $fullUrl;
        $thumbnailUrl   =  Utils::getAppUrl() . $thumbnailUrl;
    	$html   =   "<td style=\"text-align: center\" id=\"$radImageId\">";
        $html  .=   "<div class=\"thumbnail_wrapper\" style=\"height: 170px; width: 170px;\">";
        $html  .=   "<a class=\"gallery\" href=\"" . $fullUrl . "\"><img border=\"0\" src=\"" . $thumbnailUrl . "\" /></a>";
        $html  .=   "</div><br/>";
        if ($showDelButton) {
	        $html  .=   "<div style=\"text-align: right; width: 170px;\">";
	        $html  .=   "<a href=\"javascript:deleteRadImage($radImageId);\"><img border=\"0\" src=\"../images/round_delete_24x24.png\" /></a>";
	        $html  .=   "</div>";
        }
        $html  .=   "</td>";
        $this->logger->debug("Build image html block. Result: " . $html);
        return $html;
    }

    public function getRadImageHTML($radTicketItemId, $showDelButton = true) {
        $imageList  =   ORDataObject::factory('RadResultImage')->getRadImagesByTicketItem($radTicketItemId);
        $html       =   "<table id='radImageTbl'><tbody>";
        $maxCol     =   3;
        $i          =   1;
        $count      =   count($imageList);
        foreach ($imageList as $imageInfo) {
            if ($i %  $maxCol == 1) {
                $html   .=  "<tr>" . $this->buildImageBlock($imageInfo['id'], $imageInfo['full_url'], $imageInfo['thumnail_url'], $showDelButton);
            }
            elseif (($i %  $maxCol == 0) || ($i==$count)) {
                $html   .=  $this->buildImageBlock($imageInfo['id'], $imageInfo['full_url'], $imageInfo['thumnail_url'], $showDelButton). "</tr>";
            }
            else {
                $html   .=  $this->buildImageBlock($imageInfo['id'], $imageInfo['full_url'], $imageInfo['thumnail_url'], $showDelButton);
            }
            $i++;
        }
        $html   .=  "</tbody></table>";

        return $html;
    }

    public function actionDeleteRadImageAjax() {
    	$radImageId    =   $_GET['radImageId'];
    	$result = array(
                    'error'     =>  array('code' => CoreErrorCode::NORMAL,
                                          'mess' => ''),
                    'result'    =>  ''
        );
        $this->logger->info("Start action deleteRadImageAjax {radImageId=$radImageId}");
        ORDataObject::factory('RadResultImage')->deleteImage($radImageId);
        $this->logger->info("Finish action deleteRadImageAjax {radImageId=$radImageId}");

        return json_encode($result);
    }

    public function actionLoadRadResultViewPage($ticketId = 0) {
    	$result = array(
                    'error'     =>  array('code' => CoreErrorCode::NORMAL,
                                          'mess' => ''),
                    'result'    =>  ''
        );
        try {
	        // All opening ticket of patient
	        $rawList        =   ORDataObject::factory('RadTicket')->getAssignmentsByTicket($ticketId);
	        $ticketList     =   RadUtils::getAssignmentListKeyValue($rawList, true);
	        $this->assign('radTicketList', $ticketList);
            $result['result']   =   $this->view->render('result_view.html');
        }
        catch (Exception $ex) {
        	$result['result']  =   CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
            $this->logger->error('Action loadRadResultViewPage fails. Error message: ' . $ex->getMessage());
        }

        return $result['result'];
    }

    public function actionLoadResultViewAjax($radTicketId = 0) {
        $result = array(
                    'error'     =>  array('code' => CoreErrorCode::NORMAL,
                                          'mess' => ''),
                    'result'    =>  ''
        );
        $radTicketId    =   EnforceType::int($_GET['radTicketId']);
        $this->logger->info("Start action LoadResultViewAjax {radTicketId=$radTicketId}");
        try {
            $objRadTicket   =   Celini::newORDO('RadTicket', $radTicketId);
            $objProcessor   =   RadProcessorFactory::createProcessor($objRadTicket->getEnumRadType());
            $result['result']   =   $objProcessor->loadResultView($radTicketId);
        }
        catch(RadException $ex) {
            $result['error']['code']    =   $ex->getErrorCode();
            $result['error']['mess']    =   CoreErrorCode::getErrorMess($ex->getErrorCode());
            $this->logger->error('Action StartTicket fail. Error message: '. $ex->getMessage());
        }
        catch(Exception $ex){
            $result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
            $this->logger->error('Action StartTicket fail. Error message: '. $ex->getMessage());
        }
        $this->logger->info("Finish action LoadResultInputAjax {radTicketId=$radTicketId}");

        return json_encode($result);
    }
}
?>